﻿using System;
using System.Diagnostics;
using Assignment_2.Entities;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace Assignment_2
{
    class Input
    {
        private readonly Game1 _game;

        private Quaternion _quatRotation = Quaternion.Identity;
        private Matrix _rot = Matrix.Identity;
        private const float RotationSpeed = 1f;
        private float _speed = 0.0f;
        private Vector3 _pr = Vector3.Zero;

        private float _upDownRotation = 0;
        private float _leftRigtRotation = 0;
        private float _rollRotation = 0;

        public Input(Game1 game)
        {
            _game = game;
        }

        public void Update(GameTime gt)
        {
            if (Keyboard.GetState().IsKeyDown(Keys.Escape) || GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
                _game.Exit();

            var dT = (float)gt.ElapsedGameTime.TotalSeconds;
            //_upDownRotation = 0;
            _leftRigtRotation = 0;
            //_rollRotation = 0;

            //if (Keyboard.GetState().IsKeyDown(Keys.Up))
            //{
            //    _upDownRotation = -RotationSpeed * dT;
            //    _pr.Z -= RotationSpeed * dT;
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.Down))
            //{
            //    _upDownRotation = +RotationSpeed * dT;
            //    _pr.Z += RotationSpeed * dT;
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.Left))
            //{
            //    _rollRotation = -RotationSpeed * dT;
            //    _pr.X -= RotationSpeed * dT;
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.Right))
            //{
            //    _rollRotation = +RotationSpeed * dT;
            //    _pr.X += RotationSpeed * dT;
            //}
            if (Keyboard.GetState().IsKeyDown(Keys.D))
            {
                _leftRigtRotation = 5;
                _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position + new Vector3(.5f, 0, 0);
                ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            }
            if (Keyboard.GetState().IsKeyDown(Keys.A))
            {
                _leftRigtRotation = -5;
                _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position + new Vector3(-.5f, 0, 0);
                ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            }
            if (Keyboard.GetState().IsKeyDown(Keys.W))
            {
                _leftRigtRotation = 10;
                _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position + new Vector3(0, .5f, 0);
                ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            }
            if (Keyboard.GetState().IsKeyDown(Keys.S))
            {
                _leftRigtRotation = -10;
                _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position + new Vector3(0, -.5f, 0);
                ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            }
            //if (Keyboard.GetState().IsKeyDown(Keys.D))
            //{
            //    _leftRigtRotation = -RotationSpeed * dT;
            //    _pr.Y -= RotationSpeed * dT;
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.A))
            //{
            //    _leftRigtRotation = +RotationSpeed * dT;
            //    _pr.Y += RotationSpeed * dT;
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.W))
            //{
            //    _speed += 1.1f * dT;
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.S))
            //{
            //    _speed -= 1.1f * dT;
            //}

            //if (Keyboard.GetState().IsKeyDown(Keys.I))
            //{
            //    _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position + new Vector3(0, .5f, 0);
            //    ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.K))
            //{
            //    _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position - new Vector3(0, .5f, 0);
            //    ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.J))
            //{
            //    _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position + new Vector3(.5f, 0, 0);
            //    ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            //}
            //if (Keyboard.GetState().IsKeyDown(Keys.L))
            //{
            //    _game.Entities[EntityNames.Typhoon].Position = _game.Entities[EntityNames.Typhoon].Position - new Vector3(.5f, 0, 0);
            //    ((Typhoon)_game.Entities[EntityNames.Typhoon]).WalkAnimation();
            //}

            if (Keyboard.GetState().IsKeyDown(Keys.Z))
            {
                _game.Entities[EntityNames.Ocean].Scale -= 0.01f * dT;
            }
            if (Keyboard.GetState().IsKeyDown(Keys.X))
            {
                _game.Entities[EntityNames.Ocean].Scale += 0.01f * dT;
            }

            //Quaternion additionalRotation = Quaternion.CreateFromAxisAngle(Vector3.Forward, _upDownRotation) * Quaternion.CreateFromAxisAngle(Vector3.Up, _leftRigtRotation) * Quaternion.CreateFromAxisAngle(Vector3.Right, _rollRotation);
            Quaternion additionalRotation = Quaternion.CreateFromAxisAngle(Vector3.Up, _leftRigtRotation);
            _quatRotation *= additionalRotation;
            //_rot = Matrix.CreateFromQuaternion(_quatRotation);


            //_game.Camera.Position += _rot.Right * _speed;
            _rot = Matrix.CreateFromAxisAngle(Vector3.Up, _leftRigtRotation);

            var tPos = _game.Entities[EntityNames.Typhoon].Position;

            tPos.X += (_rot.Right.X * _speed) * ((float)((World)_game.Entities[EntityNames.World]).Heightmap.Width / ((World)_game.Entities[EntityNames.World]).Heightmap.Height);
            tPos.Y += (_rot.Right.Z * _speed) * ((float)((World)_game.Entities[EntityNames.World]).Heightmap.Height / ((World)_game.Entities[EntityNames.World]).Heightmap.Width);

            if (tPos.X <= 0)
                tPos.X = ((World)_game.Entities[EntityNames.World]).Heightmap.Width;
            if (tPos.X > ((World)_game.Entities[EntityNames.World]).Heightmap.Width - 1)
                tPos.X = 0;
            if (tPos.Y <= 0)
                tPos.Y = ((World)_game.Entities[EntityNames.World]).Heightmap.Height;
            if (tPos.Y > ((World)_game.Entities[EntityNames.World]).Heightmap.Height - 1)
                tPos.Y = 0;
            _game.Entities[EntityNames.Typhoon].Position = tPos;

            _game.Camera.Position =
                    ((World)_game.Entities[EntityNames.World]).ConvertToSphere(
                        _game.Entities[EntityNames.Typhoon].Position);

            Matrix offset = Matrix.CreateRotationX(-1.6f);

            _game.Camera.Rotation = offset *Matrix.CreateFromQuaternion(GetRotation(Vector3.Forward, Vector3.Normalize(_game.Camera.Position - new Vector3(0f, 0f, 0f)), Vector3.Up));
            _game.Entities[EntityNames.Typhoon].Rotation = _rot * _game.Camera.Rotation;

        }

        public static Quaternion GetRotation(Vector3 source, Vector3 dest, Vector3 up)
        {
            float dot = Vector3.Dot(source, dest);

            if (Math.Abs(dot - (-1.0f)) < 0.000001f)
            {
                return new Quaternion(up, MathHelper.ToRadians(180.0f));
            }
            if (Math.Abs(dot - (1.0f)) < 0.000001f)
            {
                return Quaternion.Identity;
            }

            var rotAngle = (float)Math.Acos(dot);
            var rotAxis = Vector3.Cross(source, dest);
            rotAxis = Vector3.Normalize(rotAxis);
            return Quaternion.CreateFromAxisAngle(rotAxis, rotAngle);
        }
    }
}
